package XunChunCPU.MEM

import chisel3._
import XunChunCPU.common.CommonConfig._ 
import XunChunCPU.common.Bundles._

class MemAccess extends Module {
    val io = IO(new Bundle{
        // 从EXE过来的信号
        val memInfo = Flipped(new MemInfo)
        val wbInfo_in = Flipped(new WBInfo)
        // 传递给WB的信号
        val wbInfo_out = new WBInfo
        // 访存信号
        val rdata = Input(UInt(32.W))
        // 数据前推
        val bypassFromMem1 = new ByPassBundle   // 去ID阶段
        val bypassFromMem2 = new ByPassBundle   // 去EXE阶段
        // 取值暂停信号
        val stallFromMEM = Output(Bool())
    })
    // 前推与传递给WB的信号
    // 给WB的信号当valid时传递
    // 如果时LB和LW，那么需要将结果放到前推，其他的都将已有的传递
    io.wbInfo_out.regAddr := io.wbInfo_in.regAddr
    io.wbInfo_out.regwe := io.wbInfo_in.regwe
    when(io.memInfo.memType === MemLB || io.memInfo.memType === MemLW) {
        io.wbInfo_out.wData := io.rdata
        io.bypassFromMem1.regAddr := io.wbInfo_in.regAddr
        io.bypassFromMem1.regData := io.rdata
        io.bypassFromMem2.regAddr := io.wbInfo_in.regAddr
        io.bypassFromMem2.regData := io.rdata
    }.otherwise{
        // 访存阶段不会生成新的数据
        io.wbInfo_out.wData := io.wbInfo_in.wData
        when(io.wbInfo_in.regwe){
            // 如果指令会写入寄存器，需要前推
            io.bypassFromMem1.regAddr := io.wbInfo_in.regAddr
            io.bypassFromMem1.regData := io.wbInfo_in.wData
            io.bypassFromMem2.regAddr := io.wbInfo_in.regAddr
            io.bypassFromMem2.regData := io.wbInfo_in.wData
        }.otherwise{
            io.bypassFromMem1.regAddr := 0.U
            io.bypassFromMem1.regData := 0.U
            io.bypassFromMem2.regAddr := 0.U
            io.bypassFromMem2.regData := 0.U
        }
    }
    when(io.memInfo.memType === MemSB || io.memInfo.memType === MemSW || io.memInfo.memType === MemLB || io.memInfo.memType === MemLW){
        when(io.memInfo.memAddr(22) === 0.U){
            io.stallFromMEM := true.B
        }.otherwise{
            io.stallFromMEM := false.B
        }
    }.otherwise{
        io.stallFromMEM := false.B
    }
}